import 'dart:convert';

import 'package:floor/floor.dart';

Artist artistDaoFromJson(String str) => Artist.fromJson(json.decode(str));

String artistDaoToJson(Artist data) => json.encode(data.toJson());

@Entity(tableName: "Artist", primaryKeys: ['id'])
class Artist {
  Artist(
      {this.id,
      required this.uid,
      required this.name,
      required this.photo,
      required this.music,
      required this.group});

  @PrimaryKey(autoGenerate: true)
  int? id;
  String uid;
  String name;
  String photo;
  String group;
  List<String> music;

  factory Artist.fromJson(Map<String, dynamic> json) => Artist(
        id: json["id"],
        uid: json["uid"],
        name: json["name"],
        photo: json["photo"],
        group: json["group"],
        music: List<String>.from(json["music"].map((x) => x)),
      );

  Map<String, dynamic> toJson() => {
        "id": id,
        "uid": uid,
        "name": name,
        "photo": photo,
        "group": group,
        "music": List<String>.from(music.map((x) => x)),
      };

  static int compare(Artist a, Artist b) {
    final firstOneChar = a.uid.substring(0, 1);
    if (firstOneChar == "U") {
      return 1;
    }
    final firstTwoChar = b.uid.substring(0, 1);
    if (firstTwoChar == "U") {
      return -1;
    }
    final firstOneNum = int.parse(firstOneChar);
    final firstTwoNum = int.parse(firstTwoChar);
    if (firstOneNum != firstTwoNum) {
      return firstOneNum - firstTwoNum;
    }

    final otherOneBinNum = int.parse(a.uid.substring(1), radix: 36);
    final otherTwoBinNum = int.parse(b.uid.substring(1), radix: 36);
    final oneCount = _getBinCountWithOne(otherOneBinNum);
    final twoCount = _getBinCountWithOne(otherTwoBinNum);
    if (oneCount != twoCount) {
      return oneCount - twoCount;
    }

    final otherOneDecNum = int.parse(otherOneBinNum.toRadixString(2));
    final otherTwoDecNum = int.parse(otherTwoBinNum.toRadixString(2));
    return otherOneDecNum - otherTwoDecNum;
  }

  static int _getBinCountWithOne(int number) {
    var count = 0;
    while (number != 0) {
      number = number & (number - 1);
      count++;
    }
    return count;
  }
}

extension ArtistModelExtension on List<Artist> {
  List<Artist> sortList() {
    sort((a, b) => Artist.compare(a, b));
    return this;
  }
}
